#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <photo_manager.h>

static int bmpIsSupport(char *filename);
static int bmpGetDispData(char *filename, PT_imageInfo image);

static T_PhotoOpr bmpOpr = 
{
	.name 			= "bmp",
	.isSupport 		= bmpIsSupport,
	.getDispData 	= bmpGetDispData,
	.next			= NULL,
};

typedef struct tagBITMAPFILEHEADER{
    unsigned short bfType;
    unsigned int  bfSize;
    unsigned short bfReserved1;
    unsigned short bfReserved2;
    unsigned int  bfOffBits;
}__attribute__((packed)) BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{
    unsigned int biSize;
    unsigned int biWidth;
    unsigned int biHeight;
    unsigned short biPlanes;
    unsigned short bitBitCount;
    unsigned int bitCompression;
    unsigned int bitSizeImage;
    unsigned int biXPelPerMeter;
    unsigned int biYPelPerMeter;
    unsigned int biClrUsed;
    unsigned int biClrImportant;
}__attribute__((packed)) BITMAPINFOHEADER;

static int bmpIsSupport(char *filename)
{
	if(filename ==NULL)
	{
		fprintf(stderr, "the parama error\n");
		return 0;
	}

	if(strstr(filename, ".bmp")==NULL)
	{
		return 0;
	}
	else
		return 1;

	return 0;

}

static int bmpGetDispData(char *filename, PT_imageInfo image)
{
	BITMAPINFOHEADER *bmpInfo;
	int fd;
	struct stat buf;
	int fd_size;
	int oneline;
	unsigned char *bmpBuff;
	unsigned char *buff;

	fd = open(filename, O_RDONLY);
	if(fd <0)
	{
		fprintf(stderr, "open file error %s\n", strerror(errno));
		return -1;
	}

	fstat(fd, &buf);
	fd_size = buf.st_size;
	bmpBuff = mmap(NULL,fd_size,PROT_READ,MAP_SHARED,fd,0);
	if(bmpBuff == MAP_FAILED)
	{
		fprintf(stderr,"bmp mmap error:%s\r\n",strerror(errno));
		return -1;	
	}

	bmpInfo = (BITMAPINFOHEADER *)(bmpBuff + sizeof(BITMAPFILEHEADER));
	image->height 			= bmpInfo->biHeight;
	image->width 			= bmpInfo->biWidth;
	image->iBpp				= bmpInfo->bitBitCount;
	image->isBMP			= 1;

	buff = malloc((image->height)*(image->width)*(image->iBpp)/8);
	oneline = (image->width)*(image->iBpp)/8;

	for(int i=0;i<image->height;i++)
	{
		memcpy(buff+oneline*i, bmpBuff+54+(((image->height)-i-1)*oneline) , oneline);
	}
	image->imageDataBuff 	= buff;

	munmap(bmpBuff, fd_size);
	close(fd);
	return 0;
}

int bmpInit(void)
{
	int ret;

	ret = registerPhotoOpr(&bmpOpr);
	return ret;
}


